package com.itheima.health.service.impl;

import com.itheima.health.common.RedisConst;
import com.itheima.health.business.ReportBusiness;
import com.itheima.health.common.ReportConst;
import com.itheima.health.dao.MemberReportDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.pojo.entity.HotSetmeal;
import com.itheima.health.pojo.vo.BusinessReportDataVO;
import com.itheima.health.pojo.vo.MemberReportVO;
import com.itheima.health.pojo.vo.SetmealCountSubVO;
import com.itheima.health.pojo.vo.SetmealReportVO;
import com.itheima.health.service.ReportService;
import com.itheima.health.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberReportDao memberReportDao;
    @Autowired
    private ReportBusiness reportBusiness;
    @Autowired
    private OrderDao orderDao;

    @Override
    public MemberReportVO getMemberReport() {
        LocalDate startDate = DateTimeUtil.getLastDateBeforeMonths(
                LocalDate.now(), ReportConst.MONTH_TWELVE);
        List<String> months = getMonths(startDate);
        List<Integer> memberCount = getMemberCount(months);
        return new MemberReportVO(months, memberCount);
    }

    @Override
    public SetmealReportVO getSetmealReportVO() {
        List<String> setmealNames = orderDao.selectSetmealNames();
        List<SetmealCountSubVO> setmealCount = orderDao.selectTop5Setmeals();
        return SetmealReportVO.builder()
                .setmealNames(setmealNames)
                .setmealCount(setmealCount)
                .build();
    }

    /**
     * 封装 MemberReportVO 的 memberCount 属性
     * @param months
     * @return
     */
    public List<Integer> getMemberCount(List<String> months) {
        List<Integer> memberCount = new ArrayList<>();
        for (String month : months) {
            Integer count = reportBusiness.getCountByMonth(month);
            memberCount.add(count);
        }
        return memberCount;
    }

    /**
     * 封装 MemberReportVO 的 months 属性
     * @param date 统计开始时间
     * @return
     */
    private static List<String> getMonths(LocalDate date) {
        List<String> months = new ArrayList<>();
        for (int i = 0; i < ReportConst.MONTH_TWELVE; i++) {
            String month = DateTimeUtil.format(date, ReportConst.PATTERN_YEAR_MONTH);
            months.add(month);
            date = date.plusMonths(1);
        }
        return months;
    }


    /**
     * @param
     * @return com.itheima.health.pojo.vo.BusinessReportDataVO
     * @Author liyichen
     * @Description 营业统计
     * @Date 9:15 2024/7/11
     */
    @Override
    public BusinessReportDataVO getBRDV() {
        Map<String, Long> memberReport = memberReportDao.findMemberStats();
        Map<String, Long> orderReport = orderDao.getOrderReport();
        List<HotSetmeal> hotSetmeals = orderDao.selectTopSetmeals();

        return BusinessReportDataVO.builder()
                .reportDate(new Date())
                .todayNewMember(memberReport.get("todayNewMember"))
                .thisWeekNewMember(memberReport.get("thisWeekNewMember"))
                .thisMonthNewMember(memberReport.get("thisMonthNewMember"))
                .totalMember(memberReport.get("totalMember"))
                .todayOrderNumber(orderReport.get("todayOrderNumber"))
                .todayVisitsNumber(orderReport.get("todayVisitsNumber"))
                .thisWeekOrderNumber(orderReport.get("thisWeekOrderNumber"))
                .thisWeekVisitsNumber(orderReport.get("thisWeekVisitsNumber"))
                .thisMonthOrderNumber(orderReport.get("thisMonthOrderNumber"))
                .thisMonthVisitsNumber(orderReport.get("thisMonthVisitsNumber"))
                .hotSetmeal(hotSetmeals)
                .build();
    }

    @Override
    public void exportBusinessReport(HttpServletResponse response) {
        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=static.xlsx");
        BusinessReportDataVO brdv = getBRDV();

        try (
                InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
                XSSFWorkbook workbook = new XSSFWorkbook(inputStream)
        ) {
            XSSFSheet sheet = workbook.getSheet("运营数据统计");
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // 将Date对象格式化为字符串
            String formattedDate = dateFormat.format(brdv.getReportDate());
            // 写入标题行
            sheet.getRow(1).getCell(1).setCellValue(formattedDate);
            // ... 其他标题

            // 写入会员数据统计
            sheet.getRow(4).getCell(2).setCellValue(brdv.getTodayNewMember());
            sheet.getRow(4).getCell(6).setCellValue(brdv.getTotalMember());
            sheet.getRow(6).getCell(2).setCellValue(brdv.getThisWeekNewMember());
            sheet.getRow(6).getCell(6).setCellValue(brdv.getThisMonthNewMember());

            // 写入预约到诊数据统计
            sheet.getRow(11).getCell(2).setCellValue(brdv.getTodayOrderNumber());
            sheet.getRow(11).getCell(6).setCellValue(brdv.getTodayVisitsNumber());
            sheet.getRow(13).getCell(2).setCellValue(brdv.getThisWeekOrderNumber());
            sheet.getRow(13).getCell(6).setCellValue(brdv.getThisWeekVisitsNumber());
            sheet.getRow(15).getCell(2).setCellValue(brdv.getThisMonthOrderNumber());
            sheet.getRow(15).getCell(6).setCellValue(brdv.getThisMonthVisitsNumber());

            // 写入热门套餐数据
            int rowIndex = 22; // 开始于第22行
            for (HotSetmeal hotSetmeal : brdv.getHotSetmeal()) {
                Row row = sheet.getRow(rowIndex);
                row.getCell(0).setCellValue(hotSetmeal.getName());
                row.getCell(2).setCellValue(hotSetmeal.getSetmeal_count());
                row.getCell(4).setCellValue(hotSetmeal.getProportion());
                rowIndex = rowIndex + 2;
            }

            try (OutputStream out = response.getOutputStream()) {
                workbook.write(out);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
